﻿///////////////////////////////////////////////////////////////////////////////
/// Copyright (c) by longshuang@msn.cn 2014.
/// All rights reserved.
///
/// @File	: Engine.Utils.hpp
/// @Brief	: 其他小工具类的集合
/// @Author	: Leo Zhao <longshuang@msn.cn>
/// @Date	: 2015-02-27
///
/// CHANGELOG
///		2015-03-18	Guard移至该空间
///		2015-02-27	增加命令行参数解析小工具Engine::Utils::Params
///////////////////////////////////////////////////////////////////////////////
#ifndef		__ENGINE_UTILS_HPP_INCLUDE__
#define		__ENGINE_UTILS_HPP_INCLUDE__

#include	<map>
#include	<functional>
#include	<string>

namespace Engine { namespace Utils {

	/// @Brief	: 命令行参数解析
	class Params {
	public:
		Params() {}
		Params(int nArgc, char * pArgv[]) { Parse(nArgc, pArgv); }
		Params(const char * szCmd) { Parse(szCmd); }
		virtual ~Params() {}

		/// @Brief	: 解析命令行传入参数（如Main函数参数）
		/// @Param	: nArgc		参数个数
		/// @Param	: pArgv		参数列表
		/// @Return	: NONE
		void		Parse(int nArgc, char * pArgv[]);

		/// @Brief	: 解析命令行参数形式的字串（如"-path=XXX --std=c++11 -noexcept"）
		/// @Param	: szCmd		命令参数
		/// @Return	: NONE
		void		Parse(const char * szCmd);

		/// @Brief	: 解析完成后用于对一个Cmd设置别名，用于统一获取
		/// @Param	: szAlias	新命令名
		/// @Param	: szOrg		原命令名
		/// @Return	: NONE
		void		Alias(const char * szAlias, const char * szOrg);

		/// @Brief	: 取得参数个数
		/// @Param	: NONE
		/// @Return	: 返回有效参数个数
		int			Num() { return _mpCmds.size(); }

		/// @Brief	: 检测是否有某个参数
		/// @Param	: szParam	参数名
		/// @Return	: True，设置了该值；False，没有设置该值
		bool		Has(const char * szCmd);

		/// @Brief	: 取得一个参数的值
		/// @Param	: szParam	参数名
		/// @Return	: 参数值
		std::string	Get(const char * szCmd);
		
	private:
		std::map<std::string, std::string>	_mpCmds;

	};

	/// @Brief	: 局部作用域辅助工具，通常会使用lambda表达式指定作用域结束时执行的操作
	class Guard {
	public:
		Guard(const std::function<void()> & fnOpt)
			: _bDismissed(false)
			, _fnOpt(fnOpt) {}
		virtual ~Guard() { if (!_bDismissed) _fnOpt(); }

		/// @Brief	: 取消在作用域结束时的执行
		/// @Param	: NONE
		/// @Return	: NONE
		inline void		Dismissed() { _bDismissed = true; }

	private:
		bool					_bDismissed;
		std::function<void()>	_fnOpt;
	};

}}

#endif//!	__ENGINE_UTILS_HPP_INCLUDE__

